home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / lib / dial / d_lock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  4.4 KB  |  190 lines

  1. #include "util.h"
  2. #include "sys/stat.h"
  3. #ifdef V4_2BSD
  4. #include <sys/file.h>
  5. #endif /* V4_2BSD */
  6. #include "d_lock.h"
  7. #include "d_returns.h"
  8.  
  9. extern    char    *lckdfldir;
  10. extern    int    d_errno;
  11.  
  12. /*
  13.  *    D_LOCK
  14.  *
  15.  *    Routine which attempts to open a file exclusively, and thereby lock
  16.  *    the associated port or direct line.
  17.  *
  18.  *    Apr 89    E. Bennett -- finally straightened out line locking.
  19.  *        see conf/site/d_lock.h
  20.  *    Apr 87    E. Bennett -- added ifdef's for ASCIILOCKS and ATTSVKILL
  21.  *
  22.  *    Feb 84    D. Long -- modified to stat the lock rather than d_verifying it
  23.  *
  24.  *    Mar 84    D. Rockwell & D. Long -- use flock instead of UUCP convention
  25.  *        D. Rockwell & D. Long -- fixed bug with d_lckfd in d_lock.
  26.  *
  27.  *    Jul 85    D. Rockwell & D. Long -- add UUCP-compatible locking (yuck)
  28.  *        This assumes that the phone line is being locked with
  29.  *        "/usr/spool/uucp/LCK..tty*"
  30.  *
  31.  *    lockfile -- lock file name
  32.  */
  33.  
  34. d_lock(lockfile)
  35. register char *lockfile;
  36. {
  37.     extern    int    d_lckfd;
  38.         char    lockername[1024];    /* full path of lockfile */
  39. #ifdef UUCPLOCK
  40.         char    tempername[1024];    /* full path of tmp file */
  41.         int    fd;
  42. #ifdef ASCIILOCKS
  43.         char    pid[SIZEOFPID+2];
  44. #else /* ASCIILOCKS */
  45.         int    pid;
  46. #endif /* ASCIILOCKS */
  47.  
  48.     d_lckfd = -1;
  49.     sprintf(tempername, "%s/MLTMP.%d", UUCPLOCK, getpid());
  50.     sprintf(lockername, "%s/%s", UUCPLOCK, lockfile);
  51. #ifdef ASCIILOCKS
  52.     sprintf(pid, "%*d\n", SIZEOFPID, getpid());
  53. #else /* ASCIILOCKS */
  54.     pid = getpid();
  55. #endif /* ASCIILOCKS */
  56.     (void) unlink(tempername);
  57.     if ((fd = creat(tempername, 0644)) < 0) {
  58. #ifdef D_LOG
  59.         d_log("d_lock", "can't create locker file '%s'", tempername);
  60. #endif /* D_LOG */
  61.         (void) unlink(tempername);    /* never needed? */
  62.         d_errno = D_LOCKERR;
  63.         return(D_FATAL);
  64.     }
  65. #ifdef ASCIILOCKS
  66.     write(fd, pid, SIZEOFPID+1);
  67. #else /* ASCIILOCKS */
  68.     write(fd, (char *)&pid, sizeof(pid));
  69. #endif /* ASCIILOCKS */
  70.     (void) close(fd);
  71.     if (link(tempername, lockername) < 0) {
  72. #define    NEED_D_VERIFY    1
  73.         if (d_verify(lockername) >= D_OK) {
  74.             (void) unlink(tempername);
  75.             return(D_NO);
  76.         }
  77.         (void) unlink(lockername);
  78.         if (link(tempername, lockername) < 0) {
  79. #ifdef D_LOG
  80.             d_log("d_lock", "can't link lock file '%s'", lockername);
  81. #endif /* D_LOG */
  82.             (void) unlink(tempername);
  83.             return(D_NO);
  84.         }
  85.     }
  86.     (void) unlink(tempername);
  87.  
  88. #else /* UUCPLOCK */
  89.     sprintf(lockername, "%s/%s", lckdfldir, lockfile);
  90. #ifndef V4_2BSD
  91. #define    NEED_D_VERIFY    1
  92.     if (d_verify(lockername) >= D_OK)
  93.         return(D_NO);        /* it's really busy */
  94.  
  95.     (void) unlink(lockername);    /* clean it out, if necessary */
  96.     if ((d_lckfd = creat(lockername, 0644)) < 0) {
  97. #else /* V4_2BSD */
  98.     if (d_lckfd < 0 && (d_lckfd = open(lockername, O_RDONLY|O_CREAT, 0644)) < 0) {
  99. #endif /* V4_2BSD */
  100. #ifdef D_LOG
  101.         d_log("d_lock", "can't create lock file '%s'", lockername);
  102. #endif /* D_LOG */
  103.         d_errno = D_LOCKERR;
  104.         return(D_FATAL);
  105.     }
  106.  
  107. #ifdef V4_2BSD
  108.     if (flock(d_lckfd, LOCK_EX|LOCK_NB) < 0) {
  109.         (void) close(d_lckfd);
  110.         d_lckfd = -1;
  111.         return(D_NO);
  112.     }
  113. #endif /* V4_2BSD */
  114. #endif /* UUCPLOCK */
  115.     return(D_OK);
  116. }
  117.  
  118. #ifdef    NEED_D_VERIFY
  119. /*
  120.  * d_verify - is the port REALLY active?
  121.  */
  122. d_verify(port)
  123. register char *port;
  124. {
  125. #ifdef ATTSVKILL
  126.     int    fd, pid;
  127. #ifdef ASCIILOCKS
  128.     char    alphapid[SIZEOFPID+2];
  129. #endif /* ASCIILOCKS */
  130.  
  131.     if ((fd = open(port, 0)) == -1) {
  132. #ifdef D_LOG
  133.         d_log("d_lock", "can't read locker file '%s'", port);
  134. #endif /* D_LOG */
  135.         return(D_NO);
  136.     }
  137.  
  138. #ifdef ASCIILOCKS
  139.     read(fd, alphapid, SIZEOFPID+1);
  140.     pid = atoi(alphapid);
  141. #else /* ASCIILOCKS */
  142.     read(fd, (char *)&pid, sizeof(pid));
  143. #endif /* ASCIILOCKS */
  144.  
  145.     if (kill(pid, 0) == -1 && errno == ESRCH) {
  146. #ifdef D_LOG
  147.         d_log("d_lock", "process %d no longer active", pid);
  148.         d_log("d_lock", "OK to remove %s", port);
  149. #endif /* D_LOG */
  150.         return(D_NO);
  151.     }
  152. #else /* ATTSVKILL */
  153.     struct    stat    statbuf;
  154.     time_t        curtime;
  155.  
  156.     if (stat(port, &statbuf) < 0)
  157.         return(D_NO);        /* really is inaccessable */
  158.  
  159.     time(&curtime);
  160.  
  161.     if (curtime > (statbuf.st_atime + (time_t)(15 * 60))) {
  162. #ifdef D_LOG
  163.         d_log("d_lock", "%s inactive for over 15 minutes, OK to unlock", port);
  164. #endif /* D_LOG */
  165.         return(D_NO);        /* inactive for over 15 minutes */
  166.     }
  167. #endif /* ATTSVKILL */
  168. #ifdef D_LOG
  169.     d_log("d_lock", "%s still active, not removed", port);
  170. #endif /* D_LOG */
  171.     return(D_OK);
  172. }
  173. #endif /* NEED_D_VERIFY */
  174.  
  175. d_unlock(lockfile)
  176. {
  177.     extern    int    d_lckfd;
  178.         char    lockername[1024];
  179.  
  180.     if (d_lckfd >= 0) {
  181. #ifdef V4_2BSD
  182.         flock(d_lckfd, LOCK_UN);
  183. #endif /* V4_2BSD */
  184.         (void) close(d_lckfd);
  185.         d_lckfd = -1;
  186.     }
  187.     sprintf(lockername, "%s/%s", lckdfldir, lockfile);
  188.     (void) unlink(lockername);
  189. }
  190.